package observer.advanced;

import java.lang.reflect.Method;

/**
 * java没有事件委托机制，可以通过自身实现
 *
 * 为委托分配了方法之后，委托将与该方法具有完全相同的行为，委托方法的使用跟其他方法一样
 * 一个委托可以搭载多个方法，方法会被依次执行，使得委托搭载的方法并不需要属于同一个类
 *
 * @author Chen Guang
 * @date 2019/4/10 0010 上午 10:16
 */
public class Event {
    /**
     * 要执行方法的对象
     */
    private Object object;
    /**
     * 要执行的方法名称
      */
    private String methodName;
    /**
     * 要执行方法的参数
      */
    private Object[] params;
    /**
     * 要执行方法的参数类型
      */
    private Class[] paramTypes;

    private Event() {}

    public Event(Object object, String methodName, Object... params) {
        this.object = object;
        this.methodName = methodName;
        this.params = params;
        contractParamTypes(this.params);
    }

    /**
     * 根据参数数组生成参数类型数组
      * @param params 要执行方法的参数
     */
    private void contractParamTypes(Object[] params){
        if(params != null){
            this.paramTypes = new Class[params.length];
            for(int i=0;i<params.length;i++){
                this.paramTypes[i] = params[i].getClass();
            }
        }
    }

    /**
     * 执行该对象的该方法
      * @throws Exception 异常
     */
    public void invoke() throws Exception{
        Method method = object.getClass().getMethod(methodName, paramTypes);
        if(method != null){
            method.invoke(object, params);
        }
    }
}
